/*
 *    This file is part of SSHTunneler.
 *
 *    Copyright 2009 Jean-Sebastien Gelinas <calestar@gmail.com>
 *
 *    SSHTunneler is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    SSHTunneler is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with SSHTunneler.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package sshtunneler.tools;

import java.awt.MenuItem;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

import sshtunneler.library.ExtensionFilter;
import sshtunneler.library.Server;
import sshtunneler.library.Tunnel;

public abstract class Tool {

	public HashMap<String, String> properties = new HashMap<String, String>();
	ToolsManager manager;
	Tunnel currentTunnel;
	Server currentServer;
	String name;
	String description;
	File from_directory;

	public abstract JMenuItem get_tunnel_tools_menu(boolean server_connected,
			boolean tunnel_connected);

	public abstract JMenuItem get_server_tools_menu(boolean server_connected);

	public abstract void init_properties();

	public void save_properties(File prop_file) {
		FileOutputStream out = null;
		try {
			Properties propfile = new Properties();
			out = new FileOutputStream(prop_file);

			for (Entry<String, String> prop : this.properties.entrySet()) {
				propfile.setProperty(prop.getKey(), prop.getValue());
			}
			propfile.store(out, "");
		} catch (FileNotFoundException ex) {
			Logger.getLogger(Tool.class.getName()).log(Level.SEVERE, null, ex);
		} catch (IOException ex) {
			Logger.getLogger(Tool.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			try {
				out.close();
			} catch (IOException ex) {
				Logger.getLogger(Tool.class.getName()).log(Level.SEVERE, null,
						ex);
			}
		}
	}

	public void load_properties(File prop_file) {
		if (!prop_file.exists()) {
			return;
		}
		FileInputStream in = null;
		try {
			Properties prop = new Properties();
			in = new FileInputStream(prop_file);
			prop.load(in);
			for (String propname : this.properties.keySet()) {
				String value = prop.getProperty(propname);
				if (value != null) {
					this.properties.put(propname, value);
				}
			}
		} catch (FileNotFoundException ex) {
			Logger.getLogger(Tool.class.getName()).log(Level.SEVERE, null, ex);
		} catch (IOException ex) {
			Logger.getLogger(Tool.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			try {
				in.close();
			} catch (IOException ex) {
				Logger.getLogger(Tool.class.getName()).log(Level.SEVERE, null,
						ex);
			}
		}

	}

	public JMenuItem get_tunnel_tools_menu(Server server, Tunnel tunnel,
			boolean server_connected, boolean tunnel_connected) {
		this.currentTunnel = tunnel;
		this.currentServer = server;
		return this.get_tunnel_tools_menu(server_connected, tunnel_connected);
	}

	public JMenuItem get_server_tools_menu(Server server,
			boolean server_connected) {
		this.currentServer = server;
		return this.get_server_tools_menu(server_connected);
	}

	protected Tunnel ask_tunnel(String msg) {
		Object ret = JOptionPane.showInputDialog(null, msg,
				"Please chose a tunnel", JOptionPane.PLAIN_MESSAGE, null,
				this.manager.getContainer().getTunnels().toArray(), null);
		if (ret == null || !(ret instanceof Tunnel)) {
			return null;
		}
		return (Tunnel) ret;
	}

	protected File ask_file(String extension, String description) {
		JFileChooser chooser = new JFileChooser();
		chooser.setMultiSelectionEnabled(false);
		ExtensionFilter filter = new ExtensionFilter(description);
		filter.add_accepted_extension(extension);
		chooser.setFileFilter(filter);

		chooser.showSaveDialog(null);

		File selection = chooser.getSelectedFile();
		if (selection == null) {
			return null;
		}

		if (!selection.getName().endsWith(extension)) {
			selection = new File(selection.getPath() + extension);
		}
		return selection;
	}

	public abstract MenuItem get_tray_tools_menu();

	public abstract JMenuItem get_main_tools_menu();

	public void reset() {
		this.currentServer = null;
		this.currentTunnel = null;
	}

	public abstract void run();

	public Tool(String name, String description) {
		this.name = name;
		this.description = description;
	}

	public String getName() {
		return this.name;
	}

	public String getDescription() {
		return this.description;
	}

	public String getProperty(String key) {
		return this.properties.get(key);
	}

	public String setProperty(String key, String value) {
		return this.properties.put(key, value);
	}

	public Set<String> getPropertyList() {
		return this.properties.keySet();
	}
}
